from PySide6.QtWidgets import (
    QWidget, QPushButton, QLabel, QSlider,
    QTextEdit, QVBoxLayout, QHBoxLayout, QMenu
)
from PySide6.QtCore import Qt, QPoint, Signal, Property, QSize
from PySide6.QtGui import QMouseEvent, QPalette, QColor, QFont, QContextMenuEvent

class DraggableComponent(QWidget):
    """可拖动组件的基类"""
    # 自定义信号
    position_changed = Signal(str, int, int)  # 组件ID，x坐标，y坐标
    lock_changed = Signal(str, bool)  # 组件ID，锁定状态
    delete_requested = Signal(str)  # 组件ID
    property_edit_requested = Signal(str)  # 新增：请求编辑组件属性
    
    def __init__(self, component_id, parent=None):
        super().__init__(parent)
        self.component_id = component_id
        self.locked = False
        self.dragging = False
        self.drag_start_position = QPoint()
        
        # 设置无边框窗口
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        
        # 设置样式 - 添加阴影和更清晰的边框
        self.setStyleSheet("""
            QWidget {
                background-color: #f8f8f8;
                border: 2px solid #cccccc;
                border-radius: 6px;
            }
        """)
        
        # 启用样式表
        self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
        
        # 初始布局 - 增加内边距
        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(12, 12, 12, 12)
        self.layout.setSpacing(12)
        
        # 标题栏（用于拖动）
        self.header = QWidget()
        self.header.setStyleSheet("background-color: #e0e0e0; border-radius: 4px; border: none;")
        self.header.setMinimumHeight(30)  # 确保标题栏高度足够
        self.header_layout = QHBoxLayout(self.header)
        self.header_layout.setContentsMargins(10, 5, 10, 5)
        
        # 标题和锁定图标
        self.title_label = QLabel(component_id)
        title_font = QFont()
        title_font.setBold(True)
        title_font.setPointSize(11)
        self.title_label.setFont(title_font)
        self.title_label.setStyleSheet("border: none;")
        self.title_label.setMinimumWidth(150)  # 增加标题最小宽度确保文字完整显示
        self.title_label.setMaximumHeight(20)  # 限制标题高度
        self.title_label.setWordWrap(False)    # 防止标题换行
        self.title_label.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
        
        # 锁定状态指示标签
        self.lock_indicator = QLabel("🔓")
        self.lock_indicator.setStyleSheet("border: none; font-size: 16px;")
        self.lock_indicator.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
        self.lock_indicator.setCursor(Qt.CursorShape.PointingHandCursor)
        self.lock_indicator.setMinimumWidth(30)  # 确保锁定图标有足够空间
        self.lock_indicator.mousePressEvent = self.toggle_lock
        
        self.header_layout.addWidget(self.title_label, 4)  # 增大标题占用空间比例
        self.header_layout.addWidget(self.lock_indicator, 0)
        
        self.layout.addWidget(self.header)
        
        # 添加分隔线
        separator = QWidget()
        separator.setFixedHeight(1)
        separator.setStyleSheet("background-color: #dddddd; border: none;")
        self.layout.addWidget(separator)
        
        # 内容容器 - 增加内边距，确保内容有足够空间
        self.content = QWidget()
        self.content.setStyleSheet("border: none; background-color: transparent;")
        self.content_layout = QVBoxLayout(self.content)
        self.content_layout.setContentsMargins(8, 10, 8, 10)
        self.content_layout.setSpacing(12)
        self.layout.addWidget(self.content)
        
        # 设置最小尺寸以确保组件不会太小
        self.setMinimumSize(220, 120)
        
        # 启用右键菜单
        self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.customContextMenuRequested.connect(self.show_context_menu)
    
    def show_context_menu(self, position):
        """显示右键菜单"""
        menu = QMenu()
        
        # 添加编辑属性选项
        edit_action = menu.addAction("编辑属性")
        edit_action.triggered.connect(self.request_edit_properties)
        
        # 添加分隔线
        menu.addSeparator()
        
        # 添加删除选项
        delete_action = menu.addAction("删除组件")
        delete_action.triggered.connect(self.request_delete)
        
        menu.exec(self.mapToGlobal(position))
    
    def request_delete(self):
        """请求删除该组件"""
        self.delete_requested.emit(self.component_id)
    
    def request_edit_properties(self):
        """请求编辑组件属性"""
        self.property_edit_requested.emit(self.component_id)
    
    def sizeHint(self):
        """提供默认的尺寸建议"""
        return QSize(250, 150)
    
    def mousePressEvent(self, event: QMouseEvent):
        """鼠标按下事件"""
        if event.button() == Qt.MouseButton.LeftButton and not self.locked:
            # 仅当点击标题栏区域时才允许拖动
            if self.header.geometry().contains(event.position().toPoint()):
                self.dragging = True
                self.drag_start_position = event.position().toPoint()
                self.setCursor(Qt.CursorShape.SizeAllCursor)
        super().mousePressEvent(event)
    
    def mouseMoveEvent(self, event: QMouseEvent):
        """鼠标移动事件"""
        if self.dragging and not self.locked:
            delta = event.position().toPoint() - self.drag_start_position
            new_pos = self.pos() + QPoint(delta.x(), delta.y())
            self.move(new_pos)
            # 发射位置改变信号
            self.position_changed.emit(self.component_id, new_pos.x(), new_pos.y())
        super().mouseMoveEvent(event)
    
    def mouseReleaseEvent(self, event: QMouseEvent):
        """鼠标释放事件"""
        if event.button() == Qt.MouseButton.LeftButton and self.dragging:
            self.dragging = False
            self.setCursor(Qt.CursorShape.ArrowCursor)
        super().mouseReleaseEvent(event)
    
    def toggle_lock(self, event=None):
        """切换锁定状态"""
        self.locked = not self.locked
        self.update_lock_indicator()
        # 发射锁定状态改变信号
        self.lock_changed.emit(self.component_id, self.locked)
    
    def update_lock_indicator(self):
        """更新锁定状态指示器"""
        if self.locked:
            self.lock_indicator.setText("🔒")
            # 设置背景颜色为浅红色表示锁定
            self.header.setStyleSheet("background-color: #ffdddd; border-radius: 4px; border: none;")
        else:
            self.lock_indicator.setText("🔓")
            # 恢复默认背景颜色
            self.header.setStyleSheet("background-color: #e0e0e0; border-radius: 4px; border: none;")
    
    def set_locked(self, locked):
        """设置锁定状态"""
        self.locked = locked
        self.update_lock_indicator() 